function gadget:GetInfo()
	return {
		name = "Jump",
		desc = "Introduces the jump command",
		author = "KDR_11k (David Becker)", -- I only added multiple level support
		date = "2007-12-14",
		license = "none yet",
		layer = 3,		-- low enough - so that engine specific lua calls the globals after they're initialized here
		enabled = true
	}
end

local CMD_JUMP = 32298
local jumpLvl = {}

if (gadgetHandler:IsSyncedCode()) then

--SYNCED
				--contains info about the unittypes that can jump - remove this here huh? well - can leave and just set the Knights as GG - yeah better so.
local jumpData = {		-- this all goes to config, once it's working
	[UnitDefNames.knight.id] = {
		[1] = {		-- ok - need to set this to a table in a table I guess... ah, that means the one in jump needs to be table in table, huh... ah - no just set it to new values! (unless we wanted insane amount of ability levels for it...)
			distance=300,		-- okay these are probably the paramaters for the jump
			delay=300,			-- huh ?	-- ah! the cooldown :P
			hspeed=3,			-- horizontal speed - probably want to lower this
			vspeed=1			-- this as well though
		},
		-- hmm - it only needs to "change it" at the next call, right ? so no need to "constantly check for it"...
		[2] = {		-- could also pass on "jumplevel - 2" and then let jump change it (but that would require constant checks there... or use multiple levels in the table their after all? But may be cleaner after all -- if I want to set this up with configs...
			distance=500,																															-- want to ensure easy use and modularity, anyhows..
			delay=300,
			hspeed=6,
			vspeed=2
		},
		[3] = {
			distance=700,		-- do I need to mark as indices ? Ve shall zee. Ah, the Lua manual tells me this is equivalent to ["bladibla"] = whatever
			delay=300,
			hspeed=9,
			vspeed=3
		},
	},
	-- other units with other level defs would come here.
}

local knight = {} --contains the currently jumping units -- in that case, it might want renaming...
	-- id :
	-- direction
	-- vspeed
local jumpDesc = {
	name="Jump",
	tooltip="jump over a certain distance",
	action="jump",
	id=CMD_JUMP,
	type=CMDTYPE.ICON_MAP,
	cursor="Unload units",
}
local closeinList = {} --Marks which units should close in to which radius to which location
	-- id:
	-- posx, posy, posz,
	-- radius
local teamJump = {}	-- umm is this squad specific stuff ? doh...
local jumpOffset = {}

local orderJumpList={}

function gadget:Initialize()
	-- not using the following, I don't think - and setting the stuff in the UnitDef ? I don't know... maybe later consider

	-- for i,u in pairs(UnitDefs) do
		-- if u.customParams.jumpDistance then
			-- local j = {			-- ah - this is if the values where in the Unitlua - right ?
				-- distance = toNumber(u.customParams.jumpdistance),
				-- delay = toNumber(u.customParams.jumpdelay) * 30,
				-- hspeed = toNumber(u.customParams.jumpspeed),
				-- vspeed = toNumber(u.customParams.jumpvert)
			-- }
			-- jumpData[i]=j
		-- end
	-- end

	-- jumpData[UnitDefNames.knight.id] = {
		-- distance=700,		-- okay these are probably the paramaters for the jump
		-- delay=300,			-- huh ?
		-- hspeed=9,			-- horizontal speed - probably want to lower this
		-- vspeed=3			-- this as well though
	-- }
	-- ah noes -- need to call it from a global value (set in Knight.lua) and there it's a table :P
	-- GG.jumpData[UnitDefNames.knight.id] = jumpData[UnitDefNames.knight.id] -- might be the way to do it

	-- GG.jumpData = jumpData

	GG.jumpLvl = jumpLvl -- oh. so we're making it global, but not setting a value - nice :P. Ah - we don't necessarily have to - initialisation is in "Knight.lua" at the moment, just need to ensure there are no calls before it's set..
	-- instead of jumpdata, we want the jumpLvl
	-- which will be defined as global in "Knight.lua", and called here --erm, it's vice versa for the moment - but defining at the place it's manipulated makes more sense to me.
	_G.knight=knight
	_G.jumpData=jumpData -- hmm, could this bugger me about ?
end

function gadget:AllowCommand(unit, def, team, cmd, param, opts,tag,synced)
	if cmd == CMD_JUMP then
		local jumpIsatLevel = _G.AllEngines:GetEngineByUnitID(unit):GetAbilityLvl(0)
		if jumpData[def][jumpIsatLevel] then
			if not opts.ctrl then
				if not Spring.GetGroundBlocked(param[1], param[3]) then
					if not opts.alt then
						if not teamJump[team] then
							teamJump[team] = {count = 0,x = 0, z = 0}
						end
						teamJump[team].count = teamJump[team].count + 1
						local x,y,z = Spring.GetUnitPosition(unit)
						teamJump[team].x = teamJump[team].x + x
						teamJump[team].z = teamJump[team].z + z
						return true
					else
						if not knight[unit] and not teamJump[team] then
							teamJump[team]= {count = 0,x = 0, z = 0}
							return true
						end
					end
				end
			else
				return false
			end
		end
		return false
	end
	return true
end

function gadget:CommandFallback(unit, def, team, cmd, params, opts)
	if cmd == CMD_JUMP then
		local jumpIsatLevel =  _G.AllEngines:GetEngineByUnitID(unit):GetAbilityLvl(0)

		if not knight[unit] then
			orderJumpList[unit]=params
			local x,y,z = Spring.GetUnitPosition(unit)
			local tx,ty,tz
			tx = params[1]
			ty = params[2]
			tz = params[3]
			if teamJump[team] and teamJump[team].count > 0 then
				jumpOffset[unit] = {x = teamJump[team].x / teamJump[team].count - x, z = teamJump[team].z / teamJump[team].count - z}
				tx = tx - jumpOffset[unit].x
				tz = tz - jumpOffset[unit].z
			elseif not jumpOffset[unit] then
				jumpOffset[unit] = {x = 0, z = 0}
			else
				tx = tx - jumpOffset[unit].x
				tz = tz - jumpOffset[unit].z
			end
			local dist = math.sqrt((x-tx)*(x-tx) + (z-tz)*(z-tz))
			if dist <= jumpData[def][jumpIsatLevel].distance then
				local j = {}
				j.direction=Spring.GetHeadingFromVector(tx-x, tz-z)
				j.vspeed = dist / 2 * jumpData[def][jumpIsatLevel].vspeed / jumpData[def][jumpIsatLevel].hspeed
				j.coolDown = Spring.GetGameFrame() + jumpData[def][jumpIsatLevel].delay
				j.jumping = true
				Spring.MoveCtrl.Enable(unit)
				Spring.SetUnitCOBValue(unit, 82, j.direction)
				Spring.CallCOBScript(unit, "JumpStart", 0)	-- huh ?
				SendToUnsynced("sound","sounds/jumpstart.wav",x,y,z)		-- if we don't have this - likely errors..
				--Spring.SetUnitRotation(unit, 0,j.direction,0)
				knight[unit]=j
--				closeinList[unit] = {
--					posx = tx,
--					posy = ty,
--					posz = tz,
--					radius = 0
--				}
				return true, true
			else
				closeinList[unit] = {
					posx = tx,
					posy = ty,
					posz = tz,
					radius = jumpData[def][jumpIsatLevel].distance
				}
				return true, false
			end
		else
			return true, false
		end
	end
	return false
end

function gadget:UnitCreated(unit, def, team)
	--local jumpIsatLevel = jumpLvl[team]
	-- without [jumpIsatLevel] ?? - just checking if the def is one of those in jumpData, after all
	-- ok - wasn't working cause of somewhat quirky initialisation in Knight.lua - need to fix that (else we still have problem when order is called before gameframe 10, I'm sure..
	if jumpData[def] then		-- so - this is where it fails?
		--Spring.InsertUnitCmdDesc(unit,jumpDesc)
	end
end

function gadget:UnitDestroyed(unit, def, team, aunit, adef, ateam)
	knight[unit]=nil
	jumpOffset[unit] = nil
end

function gadget:GameFrame(f)
	for u,params in pairs(orderJumpList) do
		Spring.GiveOrderToUnit(u,CMD_JUMP,params,{"ctrl"}) --this gets blocked on the leader unit but forwarded to the squad
		orderJumpList[u]=nil
	end
	for unit, j in pairs(knight) do
		local jumpIsatLevel = _G.AllEngines:GetEngineByUnitID(unit):GetAbilityLvl(0)

		if j.jumping then
			local def = Spring.GetUnitDefID(unit)
			Spring.MoveCtrl.SetRelativeVelocity(unit, 0, j.vspeed, jumpData[def][jumpIsatLevel].hspeed)
			j.vspeed = j.vspeed - jumpData[def][jumpIsatLevel].vspeed
			local x,y,z = Spring.GetUnitBasePosition(unit)
			if y < Spring.GetGroundHeight(x,z) then
				j.jumping = false
				Spring.MoveCtrl.Disable(unit)
				Spring.CallCOBScript(unit, "JumpEnd", 0)
				Spring.GiveOrderToUnit(unit,CMD.INSERT,{0,CMD.MOVE,0,x,y,z},{"alt"})
				SendToUnsynced("sound","sounds/jumpend.wav",x,y,z)		-- and the other
			end
		elseif j.coolDown < f then
			knight[unit] = nil
		end
	end
	for team, _ in pairs(teamJump) do
		teamJump[team]=nil
	end
	for unit, goal in pairs(closeinList) do
		Spring.SetUnitMoveGoal(unit, goal.posx, goal.posy, goal.posz, goal.radius)
		closeinList[unit]=nil
	end
end


else
--UNSYNCED

function gadget:RecvFromSynced(msg,file,x,y,z)
	if msg == "sound" then
		Spring.PlaySoundFile(file,5,x,y,z)
	end
end

function gadget:DrawWorld()		-- will need to change this - not draw per unit, but on the ability button
	local team = Spring.GetLocalAllyTeamID()	-- allyteam? is that the one I want?
	local f = Spring.GetGameFrame()
	for u,d in spairs(SYNCED.knight) do
		if Spring.GetUnitAllyTeam(u)==team and  d.coolDown > f then
			local ud = Spring.GetUnitDefID(u)
			gl.PushMatrix()
			local x,y,z = Spring.GetUnitPosition(u)
			gl.Translate(x,y,z)
			gl.Billboard()
			gl.Color(.2,.2,.2,1)
			gl.Rect(-21,-24,21,-16)
			gl.Color(.7,.7,0,1)
			gl.Rect(-20,-23,-20 + 40 * (1+(f - d.coolDown)/SYNCED.jumpData[ud][1].delay),-17)	-- hack !! - not check for the delay of the actual level, just use that from level 1
			gl.PopMatrix()
		end
	end
	gl.Color(1,1,1,1)
end

function gadget:Initialize()
	Spring.SetCustomCommandDrawData(CMD_JUMP,"Unload units",{.2,.2,1,1})
end

end